zynqmp: pm: Implement PLL set parameter EEMI API
authorJolly Shah <[email protected]>
Wed, 2 Jan 2019 20:27:00 +0000 (12:27 -0800)
committerJolly Shah <[email protected]>
Fri, 4 Jan 2019 19:13:41 +0000 (11:13 -0800)
This API will be used to set a parameter for the PLL. The parameter
value that is set will have effect once the PLL mode is set to integer
or fractional mode. Parameter values represent the values as defined
in the Zynq MPSoC register reference manual ug1087.

Signed-off-by: Mirela Simonovic <[email protected]>
Acked-by: Will Wong <[email protected]>
Signed-off-by: Jolly Shah <[email protected]>
plat/xilinx/zynqmp/pm_service/pm_api_sys.c
plat/xilinx/zynqmp/pm_service/pm_api_sys.h
plat/xilinx/zynqmp/pm_service/pm_defs.h
plat/xilinx/zynqmp/pm_service/pm_svc_main.c

index e85b2cee338b09883799bf7a98d5e59525d260de..9bc11f26b34c43cd87b64e5fa46ddeb729b516ee 100644 (file)
@@ -1237,3 +1237,34 @@ enum pm_ret_status pm_fpga_read(uint32_t reg_numframes,
                         address_high, readback_type);
        return pm_ipi_send_sync(primary_proc, payload, value, 1);
 }
+
+/*
+ * pm_pll_set_parameter() - Set the PLL parameter value
+ * @nid                Node id of the target PLL
+ * @param_id   ID of the PLL parameter
+ * @value      Parameter value to be set
+ *
+ * Setting the parameter will have physical effect once the PLL mode is set to
+ * integer or fractional.
+ *
+ * @return     Error if an argument is not valid or status as returned by the
+ *             PM controller (PMU)
+ */
+enum pm_ret_status pm_pll_set_parameter(enum pm_node_id nid,
+                                       enum pm_pll_param param_id,
+                                       unsigned int value)
+{
+       uint32_t payload[PAYLOAD_ARG_CNT];
+
+       /* Check if given node ID is a PLL node */
+       if (nid < NODE_APLL || nid > NODE_IOPLL)
+               return PM_RET_ERROR_ARGS;
+
+       /* Check if parameter ID is valid and return an error if it's not */
+       if (param_id >= PM_PLL_PARAM_MAX)
+               return PM_RET_ERROR_ARGS;
+
+       /* Send request to the PMU */
+       PM_PACK_PAYLOAD4(payload, PM_PLL_SET_PARAMETER, nid, param_id, value);
+       return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+}
index fee91cdd9989f50079353c7999c74fc9991a1632..acef4906c9a7d5571f30ace1075624cdde342e3e 100644 (file)
@@ -176,4 +176,8 @@ enum pm_ret_status pm_aes_engine(uint32_t address_high,
                                 uint32_t address_low,
                                 uint32_t  *value);
 
+enum pm_ret_status pm_pll_set_parameter(enum pm_node_id nid,
+                               enum pm_pll_param param_id,
+                               unsigned int value);
+
 #endif /* PM_API_SYS_H */
index 7a0d9785000b978b1974502a05caadab21e44741..fe965c5396e984391a554151ab0563cd865806cb 100644 (file)
@@ -92,6 +92,8 @@ enum pm_api_id {
        /* FPGA PL Readback */
        PM_FPGA_READ,
        PM_SECURE_AES,
+       /* PLL control API functions */
+       PM_PLL_SET_PARAMETER,
        PM_API_MAX
 };
 
@@ -265,4 +267,31 @@ enum pm_shutdown_subtype {
        PMF_SHUTDOWN_SUBTYPE_SYSTEM,
 };
 
+/**
+ * @PM_PLL_PARAM_DIV2:         Enable for divide by 2 function inside the PLL
+ * @PM_PLL_PARAM_FBDIV:        Feedback divisor integer portion for the PLL
+ * @PM_PLL_PARAM_DATA:         Feedback divisor fractional portion for the PLL
+ * @PM_PLL_PARAM_PRE_SRC:      Clock source for PLL input
+ * @PM_PLL_PARAM_POST_SRC:     Clock source for PLL Bypass mode
+ * @PM_PLL_PARAM_LOCK_DLY:     Lock circuit config settings for lock windowsize
+ * @PM_PLL_PARAM_LOCK_CNT:     Lock circuit counter setting
+ * @PM_PLL_PARAM_LFHF:         PLL loop filter high frequency capacitor control
+ * @PM_PLL_PARAM_CP:           PLL charge pump control
+ * @PM_PLL_PARAM_RES:          PLL loop filter resistor control
+ */
+enum pm_pll_param {
+       PM_PLL_PARAM_DIV2,
+       PM_PLL_PARAM_FBDIV,
+       PM_PLL_PARAM_DATA,
+       PM_PLL_PARAM_PRE_SRC,
+       PM_PLL_PARAM_POST_SRC,
+       PM_PLL_PARAM_LOCK_DLY,
+       PM_PLL_PARAM_LOCK_CNT,
+       PM_PLL_PARAM_LFHF,
+       PM_PLL_PARAM_CP,
+       PM_PLL_PARAM_RES,
+       PM_PLL_PARAM_MAX,
+};
+
+
 #endif /* PM_DEFS_H */
index 7790c979dfbeb405632d89e09cbd959a343ef91a..7430110039436f23b56c24c4ec8194de318c1d85 100644 (file)
@@ -563,6 +563,10 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
                SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
        }
 
+       case PM_PLL_SET_PARAMETER:
+               ret = pm_pll_set_parameter(pm_arg[0], pm_arg[1], pm_arg[2]);
+               SMC_RET1(handle, (uint64_t)ret);
+
        default:
                WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
                SMC_RET1(handle, SMC_UNK);